package cn.gogpay.dcb.api.common.util;


import cn.gogpay.dcb.common.util.BeanUtils;
import cn.gogpay.dcb.common.util.lang.StringUtils;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;

/**
 * 对象转换工具类
 *
 * @author yangxianxi@gogpay.cn
 * @date 2018/7/25 13:45
 */
public class ConvertUtils {

    private static final Logger logger = LoggerFactory.getLogger(ConvertUtils.class);

    /**
     * 属性拷贝，返回指定的类型
     * @param source 原数据
     * @param newClass  新JavaBean Class
     * @param <T> 指定类型
     * @return T
     */
    @Deprecated
    public static <T> T copyProperties(@NotNull Object source, @NotNull Class<T> newClass) {
        try {
            Object newObj = newClass.newInstance();
            logger.info("原数据:{}", source);
            BeanUtils.copyProperties(source, newObj);
            return (T) newObj;
        } catch (InstantiationException e) {
            logger.error("实例化对象失败", e);
        } catch (IllegalAccessException e) {
            logger.error("访问构造方法失败", e);
        } catch (InvocationTargetException e) {
            logger.error("反射异常", e);
        }
        return null;
    }

    /**
     * 属性拷贝，返回指定的类型
     * @param json json字符串
     * @param newClass 新JavaBean Class
     * @param <T> 传入类型
     * @return T
     */
    public static <T> T copyProperties(@NotBlank String json, @NotNull Class<T> newClass) {
        return JSONObject.parseObject(json, newClass);
    }

    /**
     * 属性拷贝，返回指定的类型
     * @param keyJson json字符串
     * @param beanJson 需要转换json字符串
     * @param newClass 新JavaBean Class
     * @param <T> 传入类型
     * @return T
     */
    public static <T> T copyProperties(@NotBlank String beanJson, @NotBlank String keyJson, @NotNull Class<T> newClass) {
        JSONObject reviewJson = new JSONObject();
        Map<String, Object> keys = javaBeanToMap(keyJson);
        Map<String, Object> beanMap = javaBeanToMap(beanJson);
        keys.forEach((k, v) -> reviewJson.put(k, beanMap.get(v.toString())));
        return reviewJson.toJavaObject(newClass);
    }

    /**
     * 属性拷贝，返回指定的类型
     * @param keyJson json字符串
     * @param beanJson 需要转换json字符串
     * @param newClass 新JavaBean Class
     * @param <T> 传入类型
     * @return T
     */
    public static <T> T copyPropertiesNegate(@NotBlank String beanJson, @NotBlank String keyJson, @NotNull Class<T> newClass) {
        JSONObject reviewJson = new JSONObject();
        Map<String, Object> keys = javaBeanToMap(keyJson);
        Map<String, Object> beanMap = javaBeanToMap(beanJson);
        keys.forEach((k, v) -> reviewJson.put(v.toString(), beanMap.get(k)));
        return reviewJson.toJavaObject(newClass);
    }

    /**
     * 将Map对象转换为JavaBean
     * @param params map数据集
     * @param tClass 转换对象class
     * @param <T> 传入类型
     * @return T
     */
    public static <T> T mapToJavaBean(@NotEmpty Map<String, Object> params, Class<T> tClass) {
        String jsonStr = JSONObject.toJSONString(params);
        if (StringUtils.isEmpty(jsonStr)) {
            return null;
        }
        return JSONObject.parseObject(jsonStr, tClass);
    }


    /**
     * 将JavaBean JSON 转换为 Map<String,Object>
     *
     * @param beanJson 需要转换json字符串
     * @return Map<String, Object>
     */
    public static Map<String, Object> javaBeanToMap (@NotNull String beanJson) {
        return jsonToMap(beanJson);
    }

    /**
     * 将json字符串转换为Map
     * @param jsonStr json字符串
     * @return Map<String, Object>
     */
    public static Map<String, Object> jsonToMap(@NotNull String jsonStr) {
        return JSONObject.parseObject(jsonStr, new TypeReference<Map<String, Object>>(){});
    }

}
